package com.funsport.controller.mobile;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.funsport.common.PageResult;
import com.funsport.common.Result;
import com.funsport.common.enums.EventStatus;
import com.funsport.dto.request.CreateEventRequest;
import com.funsport.entity.Event;
import com.funsport.entity.EventSignup;
import com.funsport.entity.EventSolitaire;
import com.funsport.security.SecurityUtils;
import com.funsport.service.IEventService;
import com.funsport.service.IEventSignupService;
import com.funsport.service.IEventSolitaireService;
import com.funsport.service.IEventGroupService;
import com.funsport.service.IUserService;
import com.funsport.entity.User;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Slf4j
@Tag(name = "移动端活动", description = "移动端活动相关接口")
@RestController
@RequestMapping("/mobile/event")
@RequiredArgsConstructor
public class MobileEventController {

    private final IEventService eventService;
    private final IEventSignupService eventSignupService;
    private final IEventSolitaireService solitaireService;
    private final IEventGroupService eventGroupService;
    private final IUserService userService;
    private final com.funsport.service.WechatSecurityService securityService;

    @Operation(summary = "获取活动列表")
    @GetMapping("/list")
    public Result<PageResult<Event>> getEventList(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize,
            @RequestParam(required = false) Integer sportTypeId,
            @RequestParam(required = false) String city) {
        
        Long userId = null;
        try {
            userId = SecurityUtils.getCurrentUserId();
        } catch (Exception e) {
            // 用户未登录，只显示无俱乐部限制的活动
            log.debug("用户未登录，只显示公开活动");
        }
        
        // 将userId声明为final变量，供lambda表达式使用
        final Long finalUserId = userId;
        
        Page<Event> pageParam = new Page<>(page, pageSize);
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        
        // 状态筛选 - 默认只显示已发布的活动
        wrapper.eq(Event::getStatus, EventStatus.PUBLISHED);
        
        // 时间筛选 - 只显示未开始的活动（排除已开始的活动）
        wrapper.gt(Event::getStartTime, java.time.LocalDateTime.now());
        
        // 可见性筛选：只显示公开活动，或者用户所属俱乐部的活动
        if (finalUserId != null) {
            // 已登录用户：可以看到公开活动（包括isPublic为null的历史数据） + 自己俱乐部的非公开活动
            wrapper.and(w -> w.eq(Event::getIsPublic, true)
                    .or()
                    .isNull(Event::getIsPublic)
                    .or()
                    .apply("club_id IN (SELECT club_id FROM club_members WHERE user_id = {0} AND status = 'active')", finalUserId));
        } else {
            // 未登录用户：只能看到公开活动（包括isPublic为null的历史数据）
            wrapper.and(w -> w.eq(Event::getIsPublic, true).or().isNull(Event::getIsPublic));
        }
        
        // 运动类型筛选
        if (sportTypeId != null) {
            wrapper.eq(Event::getSportTypeId, sportTypeId);
        }
        
        // 城市筛选
        if (city != null && !city.trim().isEmpty()) {
            log.info("根据城市筛选活动: {}", city);
            wrapper.like(Event::getCity, city);
        }
        
        // 按开始时间倒序排列
        wrapper.orderByDesc(Event::getStartTime);
        
        Page<Event> result = eventService.page(pageParam, wrapper);

        PageResult<Event> pageResult = PageResult.build(
                result.getRecords(), 
                result.getTotal(), 
                page, 
                pageSize);

        return Result.success(pageResult);
    }

    @Operation(summary = "获取俱乐部活动列表")
    @GetMapping("/club/{clubId}")
    public Result<PageResult<Event>> getClubEvents(
            @PathVariable Long clubId,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        
        Page<Event> pageParam = new Page<>(page, pageSize);
        
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Event::getClubId, clubId);
        // 只显示已发布的活动，不显示已取消的活动
        wrapper.eq(Event::getStatus, EventStatus.PUBLISHED);
        wrapper.orderByDesc(Event::getStartTime);
        
        Page<Event> result = eventService.page(pageParam, wrapper);

        PageResult<Event> pageResult = PageResult.build(
                result.getRecords(), 
                result.getTotal(), 
                page, 
                pageSize);

        return Result.success(pageResult);
    }

    @Operation(summary = "获取用户参与的活动")
    @GetMapping("/my-events")
    public Result<PageResult<Event>> getMyEvents(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error("用户未登录");
        }
        
        Page<Event> pageParam = new Page<>(page, pageSize);
        
        // 查询用户参与的活动
        LambdaQueryWrapper<Event> wrapper = new LambdaQueryWrapper<>();
        wrapper.inSql(Event::getId, 
            "SELECT event_id FROM event_signups WHERE user_id = " + userId + " AND status = 'confirmed'");
        // 不显示已取消的活动
        wrapper.ne(Event::getStatus, EventStatus.CANCELLED);
        wrapper.orderByDesc(Event::getStartTime);
        
        Page<Event> result = eventService.page(pageParam, wrapper);

        PageResult<Event> pageResult = PageResult.build(
                result.getRecords(), 
                result.getTotal(), 
                page, 
                pageSize);

        return Result.success(pageResult);
    }

    @Operation(summary = "获取活动详情")
    @GetMapping("/{id}")
    public Result<Event> getEventDetail(@PathVariable Long id) {
        Event event = eventService.getById(id);
        if (event == null) {
            return Result.error("活动不存在");
        }
        
        // 增加浏览次数
        event.setViewCount(event.getViewCount() + 1);
        eventService.updateById(event);
        
        return Result.success(event);
    }

    @Operation(summary = "创建活动")
    @PostMapping("/create")
    public Result<Long> createEvent(@Valid @RequestBody CreateEventRequest request) {
        Long userId = SecurityUtils.getCurrentUserId();
        
        // 内容安全检测 - 检测活动标题和描述
        String checkText = request.getTitle() + " " + (request.getDescription() != null ? request.getDescription() : "");
        if (!securityService.checkText(checkText)) {
            log.warn("活动标题或描述包含违规内容: userId={}", userId);
            return Result.error("活动信息包含违规内容，请修改后重试");
        }
        
        Event event = new Event();
        BeanUtils.copyProperties(request, event);
        event.setCreatorId(userId);
        event.setCurrentParticipants(0);
        event.setStatus(EventStatus.PUBLISHED);
        event.setViewCount(0);
        event.setLikeCount(0);
        
        // 如果isPublic为空，默认设置为公开
        if (event.getIsPublic() == null) {
            event.setIsPublic(true);
            log.info("活动isPublic字段为空，默认设置为公开");
        }
        
        // 如果needApproval为空，默认不需要审核
        if (event.getNeedApproval() == null) {
            event.setNeedApproval(false);
        }
        
        // 处理接龙功能
        if (request.getEnableSolitaire() != null && request.getEnableSolitaire()) {
            event.setEnableSolitaire(true);
            // 设置接龙截止时间为活动开始前半小时
            event.setSolitaireCutoff(request.getStartTime().minusMinutes(30));
        } else {
            event.setEnableSolitaire(false);
        }
        
        eventService.save(event);
        log.info("活动创建成功: eventId={}, userId={}, enableSolitaire={}", 
                event.getId(), userId, event.getEnableSolitaire());
        
        // 创建者自动报名参加活动
        try {
            eventSignupService.signupEvent(userId, event.getId(), "我是活动发起人");
            log.info("活动创建者自动报名成功: eventId={}, userId={}", event.getId(), userId);
        } catch (Exception e) {
            log.warn("活动创建者自动报名失败: eventId={}, userId={}", event.getId(), userId, e);
        }
        
        // 如果启用接龙功能，创建者自动参与接龙
        if (event.getEnableSolitaire()) {
            try {
                solitaireService.joinSolitaire(event.getId(), userId, "我是活动发起人，期待大家参与！");
                log.info("活动创建者自动参与接龙成功: eventId={}, userId={}", event.getId(), userId);
            } catch (Exception e) {
                log.warn("活动创建者自动参与接龙失败: eventId={}, userId={}", event.getId(), userId, e);
            }
        }
        
        return Result.success(event.getId());
    }

    @Operation(summary = "报名参加活动")
    @PostMapping("/{id}/signup")
    public Result<Void> signupEvent(@PathVariable Long id, 
                                    @RequestParam(required = false) String note) {
        Long userId = SecurityUtils.getCurrentUserId();
        eventSignupService.signupEvent(userId, id, note);
        return Result.success("报名成功", null);
    }

    @Operation(summary = "取消报名")
    @PostMapping("/{id}/cancel")
    public Result<Void> cancelSignup(@PathVariable Long id) {
        Long userId = SecurityUtils.getCurrentUserId();
        eventSignupService.cancelSignup(userId, id);
        return Result.success("已取消报名", null);
    }

    @Operation(summary = "签到")
    @PostMapping("/{id}/checkin")
    public Result<Void> checkIn(@PathVariable Long id) {
        Long userId = SecurityUtils.getCurrentUserId();
        eventSignupService.checkIn(userId, id);
        return Result.success("签到成功", null);
    }

    @Operation(summary = "活动评价")
    @PostMapping("/{id}/rate")
    public Result<Void> rateEvent(@PathVariable Long id,
                                  @RequestParam Integer rating,
                                  @RequestParam(required = false) String review) {
        Long userId = SecurityUtils.getCurrentUserId();
        eventSignupService.rateEvent(userId, id, rating, review);
        return Result.success("评价成功", null);
    }

    @Operation(summary = "获取我的报名记录")
    @GetMapping("/my-signups")
    public Result<List<EventSignup>> getMySignups(@RequestParam(required = false) String status) {
        Long userId = SecurityUtils.getCurrentUserId();
        List<EventSignup> signups = eventSignupService.getUserSignups(userId, status);
        return Result.success(signups);
    }

    @Operation(summary = "检查是否已报名")
    @GetMapping("/{id}/has-signed-up")
    public Result<Boolean> hasSignedUp(@PathVariable Long id) {
        Long userId = SecurityUtils.getCurrentUserId();
        boolean hasSignedUp = eventSignupService.hasSignedUp(userId, id);
        return Result.success(hasSignedUp);
    }

    @Operation(summary = "获取活动参与人员列表")
    @GetMapping("/{id}/participants")
    public Result<List<Map<String, Object>>> getEventParticipants(@PathVariable Long id) {
        try {
            List<EventSignup> signups = eventSignupService.getEventParticipants(id, "confirmed");
            List<Map<String, Object>> participants = new ArrayList<>();
            
            for (EventSignup signup : signups) {
                User user = userService.getById(signup.getUserId());
                if (user != null) {
                    Map<String, Object> participant = new HashMap<>();
                    participant.put("userId", user.getId());
                    participant.put("nickname", user.getNickname());
                    participant.put("avatar", user.getAvatar());
                    participant.put("signupTime", signup.getCreatedAt());
                    participant.put("status", signup.getStatus());
                    participants.add(participant);
                }
            }
            
            return Result.success(participants);
        } catch (Exception e) {
            log.error("获取参与人员列表失败: eventId={}", id, e);
            return Result.error("获取参与人员列表失败");
        }
    }

    @Operation(summary = "取消活动", description = "只有活动创建者可以取消活动")
    @PostMapping("/{id}/cancel-event")
    public Result<Void> cancelEvent(@PathVariable Long id) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error("请先登录");
        }
        
        try {
            Event event = eventService.getById(id);
            if (event == null) {
                return Result.error("活动不存在");
            }
            
            // 检查是否是创建者
            if (!event.getCreatorId().equals(userId)) {
                return Result.error("只有活动创建者可以取消活动");
            }
            
            // 检查活动状态
            if (event.getStatus() == EventStatus.CANCELLED) {
                return Result.error("活动已取消");
            }
            
            if (event.getStatus() == EventStatus.COMPLETED) {
                return Result.error("活动已结束，无法取消");
            }
            
            // 更新活动状态为已取消
            event.setStatus(EventStatus.CANCELLED);
            eventService.updateById(event);
            
            log.info("活动已取消: eventId={}, userId={}", id, userId);
            return Result.success("活动已取消", null);
        } catch (Exception e) {
            log.error("取消活动失败: eventId={}, userId={}", id, userId, e);
            return Result.error("取消活动失败：" + e.getMessage());
        }
    }

    // ==================== 接龙相关接口 ====================

    @Operation(summary = "参与活动接龙")
    @PostMapping("/{eventId}/solitaire/join")
    public Result<String> joinSolitaire(@PathVariable Long eventId,
                                       @RequestParam(required = false) String message) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error("请先登录");
        }
        
        try {
            boolean success = solitaireService.joinSolitaire(eventId, userId, message);
            if (success) {
                return Result.success("参与接龙成功");
            } else {
                return Result.error("参与接龙失败");
            }
        } catch (Exception e) {
            log.error("参与接龙失败: eventId={}, userId={}", eventId, userId, e);
            return Result.error("参与接龙失败：" + e.getMessage());
        }
    }

    @Operation(summary = "取消活动接龙")
    @PostMapping("/{eventId}/solitaire/cancel")
    public Result<String> cancelSolitaire(@PathVariable Long eventId) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error("请先登录");
        }
        
        try {
            boolean success = solitaireService.cancelSolitaire(eventId, userId);
            if (success) {
                return Result.success("取消接龙成功");
            } else {
                return Result.error("取消接龙失败");
            }
        } catch (Exception e) {
            log.error("取消接龙失败: eventId={}, userId={}", eventId, userId, e);
            return Result.error("取消接龙失败：" + e.getMessage());
        }
    }

    @Operation(summary = "获取活动接龙列表")
    @GetMapping("/{eventId}/solitaire/list")
    public Result<List<EventSolitaire>> getSolitaireList(@PathVariable Long eventId) {
        try {
            List<EventSolitaire> solitaires = solitaireService.getEventSolitaires(eventId);
            return Result.success(solitaires);
        } catch (Exception e) {
            log.error("获取接龙列表失败: eventId={}", eventId, e);
            return Result.error("获取接龙列表失败");
        }
    }

    @Operation(summary = "检查用户是否已参与接龙")
    @GetMapping("/{eventId}/solitaire/check")
    public Result<Boolean> checkSolitaire(@PathVariable Long eventId) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.success(false);
        }
        
        try {
            boolean hasJoined = solitaireService.hasJoinedSolitaire(eventId, userId);
            return Result.success(hasJoined);
        } catch (Exception e) {
            log.error("检查接龙状态失败: eventId={}, userId={}", eventId, userId, e);
            return Result.success(false);
        }
    }

    // ==================== 活动分组相关接口 ====================

    @Operation(summary = "创建活动分组", description = "活动创建者在报名结束后创建分组，自动均匀分配参与者")
    @PostMapping("/{eventId}/groups/create")
    public Result<Void> createEventGroups(
            @PathVariable Long eventId,
            @RequestParam Integer groupCount) {
        Long creatorId = SecurityUtils.getCurrentUserId();
        if (creatorId == null) {
            return Result.error("请先登录");
        }
        
        try {
            boolean success = eventGroupService.createGroupsAndAssignParticipants(eventId, groupCount, creatorId);
            if (success) {
                return Result.success("分组创建成功", null);
            } else {
                return Result.error("分组创建失败");
            }
        } catch (Exception e) {
            log.error("创建分组失败: eventId={}, groupCount={}", eventId, groupCount, e);
            return Result.error("分组创建失败：" + e.getMessage());
        }
    }

    @Operation(summary = "获取活动分组信息", description = "查询活动的所有分组及成员详情")
    @GetMapping("/{eventId}/groups")
    public Result<List<Map<String, Object>>> getEventGroups(@PathVariable Long eventId) {
        try {
            List<Map<String, Object>> groups = eventGroupService.getEventGroupsWithMembers(eventId);
            return Result.success(groups);
        } catch (Exception e) {
            log.error("获取分组信息失败: eventId={}", eventId, e);
            return Result.error("获取分组信息失败");
        }
    }

    @Operation(summary = "获取我在活动中的分组", description = "查询当前用户在活动中的分组信息")
    @GetMapping("/{eventId}/my-group")
    public Result<Map<String, Object>> getMyGroup(@PathVariable Long eventId) {
        Long userId = SecurityUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error("请先登录");
        }
        
        try {
            Map<String, Object> group = eventGroupService.getUserGroupInEvent(eventId, userId);
            if (group != null) {
                return Result.success(group);
            } else {
                return Result.success("暂未分组", null);
            }
        } catch (Exception e) {
            log.error("获取我的分组失败: eventId={}, userId={}", eventId, userId, e);
            return Result.error("获取分组信息失败");
        }
    }

    @Operation(summary = "删除活动分组", description = "删除活动的所有分组（仅创建者）")
    @DeleteMapping("/{eventId}/groups")
    public Result<Void> deleteEventGroups(@PathVariable Long eventId) {
        Long creatorId = SecurityUtils.getCurrentUserId();
        if (creatorId == null) {
            return Result.error("请先登录");
        }
        
        try {
            boolean success = eventGroupService.deleteEventGroups(eventId);
            if (success) {
                return Result.success("分组删除成功", null);
            } else {
                return Result.error("分组删除失败");
            }
        } catch (Exception e) {
            log.error("删除分组失败: eventId={}", eventId, e);
            return Result.error("删除分组失败：" + e.getMessage());
        }
    }
}
